/* eslint-disable no-restricted-globals */
/**
 * @description 此组件为折线
 * @example
 * {idName： bar,
 *  xAxis: ['星期一', '星期二'],
 *  data: [
 *  {label: 'legend1', value:[{key: '星期一', value: 20},{key: '星期二', value: 20}]},
 * {label: 'legend2', value:[{key: '星期一', value: 20},{key: '星期二', value: 20}]}，
 * ]
 * }
 * @author gf
 * @todo 在不影响已有功能的情况下可增加props
 */

import React, { useEffect, useState } from "react";
import * as echarts from "echarts";
import * as _ from "lodash";
import styles from "./index.less";
import {
  axisLabelStyle,
  axisLineStyle,
  splitLineStyle,
  TOOLTIP_FONT_SIZE,
  yaxisLabelStyle,
  yaxisLineStyle,
} from "@/utils/echarts";
import useIoObserve from "@/hook/useIoObserve";

interface VProps {
  key: string; // 与x轴对应的值
  value: number; // y轴对应的值
}

export interface DataProps {
  label: string; // legend对应的中文
  value: VProps[];
}

export interface EventLineProps {
  idName: string; // 每一个echarts图需要一个dom来创建实例，该id用来标识唯一dom
  xAxis: string[]; // x轴为字符串数组
  legend: string[];
  data: DataProps[];
  color?: string[];
  events?: any[]; // 需要标记点的坐标
  pointLegend?: string; // 需要标记的legend
  isClickPoint?: boolean; // 为true时表示可以点击， 默认为false
  onClickPoint?: (s: string) => void; // 点击高亮点的回调
  isHoverPoint?: boolean; // 为true时表示可hover， 默认为true
  percent?: boolean;
}

const EventLine = (props: EventLineProps) => {
  const {
    idName,
    xAxis,
    data,
    legend,
    color,
    events,
    pointLegend,
    isClickPoint = false,
    isHoverPoint = true,
    onClickPoint,
    percent,
  } = props;
  // console.log( xAxis,data,legend);

  const handleMultiLineData = (arr: any, str?: string) => {
    let res: any = [];
    arr.map((v) => {
      res.push([v.key, v.value]);
    });
    // console.log('res****************',res, str);
    return res;
  };

  const options = {
    color,
    xAxis: {
      type: "category",
      data: xAxis,
      boundaryGap: false,
      offset: 5,
      axisLabel: {
        ...axisLabelStyle(),
        rotate: 30,
        fontSize: 8,
      },
      axisTick: {
        show: false,
        alignWithLabel: true,
      },
      axisLine: {
        ...axisLineStyle(),
        show: true,
      },
      splitLine: {
        show: false,
      },
    },
    yAxis: {
      type: "value",
      axisTick: {
        show: false,
        alignWithLabel: true,
      },
      ...yaxisLineStyle(),
      axisLine: {
        ...yaxisLineStyle(),
        show: true,
      },
      axisLabel: {
        ...yaxisLabelStyle(),
        inside: false,
        padding: [15, 0, 0, 0],
        fontSize: 8,
        formatter: function (value, index) {
          return value + "%";
        },
      },
      ...splitLineStyle(),
    },
    tooltip: {
      trigger: "axis",
      zIndex: 2,
      backgroundColor: "rgba(65,69,81,0.96)",
      extraCssText: "border-radius:2px",
      borderWidth: 0,
      textStyle: {
        fontSize: TOOLTIP_FONT_SIZE,
        color: "#fff",
        lineHeight: "28px",
      },
      formatter: (params) => {
        let htmlStr =
          '<div class="echarts_tooltip"><p style="margin:0">' +
          params[0].axisValue +
          "</p>";
        for (let i = 0; i < params.length; i++) {
          htmlStr += `<div ><p style="margin-right:8px" title="${
            params[i].seriesName
          }">${params[i].marker + params[i].seriesName}</p><p class="value">${
            _.isNumber(params[i].value[1]) ? params[i].value[1] : "-"
          }${percent ? "%" : ""}</p></div>`;
        }
        htmlStr += "</div>";
        return htmlStr;
      },
    },
    grid: {
      left: 10,
      right: 20,
      bottom: -6,
      top: 28,
      containLabel: true,
    },
    legend: {
      data: legend,
      icon: "rectangle",
      itemWidth: 11,
      itemHeight: 11,
      itemGap: 20,
      top: -6,
      textStyle: {
        fontSize: 10,
        color: "#35425e",
        height: 28,
        lineHeight: 28,
        padding: [0, 0, -3, 2],
        maxWidth: 50,
        overflow: "truncate",
        ellipsis: "...",
      },
      tooltip: {
        show: true,
      },
    },
    series: data.map((v) => {
      return {
        name: v.label,
        data: handleMultiLineData(v.value),
        type: "line",
        top: "22%",
        symbolSize: 12,
        showAllSymbol: true,
        // symbol:`image://${location.origin}/images/point.png`
        symbol: (value: any, params: any) => {
          // console.log(v, value);
          const i = _.findIndex(v.value, (l) => l.key === value[0]);
          if (v.value[i]?.content) {
            // console.log(v.value[i]?.content)
            return `image://${location.origin}/images/point.png`;
            // return 'circle'
          } else {
            return "none";
          }
        },
        lineStyle: {
          width: 1,
        },
        emphasis: {
          focus: "series",
          lineStyle: {
            width: 2,
          },
        },
      };
    }),
  };

  const getyAxisMinMax = (start?: number, end?: number) => {
    let min = 1000000,
      max = -100000;
    data.map((v) => {
      v.value.forEach((m) => {
        min = min > m.value ? m.value : min;
        max = max < m.value ? m.value : max;
      });
    });
    return {
      min: min,
      max: max,
    };
  };

  // 调整位置
  const refreshLablePosition = (myChart) => {
    const chartDom = document.getElementById(idName);
    // const myChart = echarts.init(chartDom)
    const opt = myChart.getOption();
    const { grid, yAxis } = opt;
    const chartWidth =
      chartDom.offsetWidth -
      grid[0].left -
      grid[0].right -
      yAxis[0].nameGap -
      13;
    const chartHeight =
      chartDom.offsetHeight - grid[0].top - grid[0].bottom - 50;

    const markPoint =
      document
        .getElementsByClassName("echarts_ponit_area")[0]
        ?.querySelectorAll(".echarts_mark_point_box") || [];

    for (let dom of markPoint) {
      // console.log(dom);

      const domSet = dom["dataset"];
      const domContent = domSet["content"];
      const domKey = domSet["key"];
      const domValue = domSet["value"];
      const curIndex = xAxis.indexOf(domKey);
      const domHeight = dom.offsetHeight;
      const domWidth = dom.offsetWidth;
      // console.log(domHeight, domWidth);

      const pBottom =
        ((domValue - getyAxisMinMax().min) /
          (getyAxisMinMax().max - getyAxisMinMax().min)) *
          chartHeight -
        domHeight +
        30;
      const pLeft =
        (curIndex / xAxis.length) * chartWidth +
        grid[0].left +
        yAxis[0].nameGap;
      if (domWidth > chartWidth - pLeft) {
        dom.style.left = pLeft + "px";
        dom.style.bottom = pBottom + "px";
        continue;
      }
      dom.style.bottom = pBottom + "px";
      dom.style.left = pLeft + "px";
    }
  };

  const hightLight = (params) => {
    const markPoint =
      document
        .getElementsByClassName("echarts_ponit_area")[0]
        ?.querySelectorAll(".echarts_mark_point_box") || [];
    markPoint.forEach((dom) => {
      if (dom["dataset"].key === params.name) {
        dom.style.visibility = "visible";
      }
    });
  };

  const removeHightLight = (params) => {
    const markPoint =
      document
        .getElementsByClassName("echarts_ponit_area")[0]
        ?.querySelectorAll(".echarts_mark_point_box") || [];
    markPoint.forEach((dom) => {
      dom.style.visibility = "hidden";
    });
  };

  const handleGenBar = () => {
    const dom = document.getElementById(idName);
    if (dom) {
      const w = parseFloat(getComputedStyle(dom).width);
      // console.log(legendData);
      const fontWidth = legend.join("")?.length * 11; // 假设每个字占12px时， 所有字需要的宽度
      const minLength = w - 40 - legend.length * 12 - (legend.length - 1) * 12;
      let legendW = 0;
      if (fontWidth > minLength) {
        legendW =
          (w - 40 - legend.length * 12 - (legend.length - 1) * 12) /
          legend.length;
        options.legend.textStyle.width = legendW ? Number(legendW) : 48;
      }
      const myChart = echarts.init(dom);
      myChart.setOption(options);

      isHoverPoint &&
        myChart.on("mouseover", "series.line", (params: any) => {
          options.tooltip.show = false;
          myChart.setOption(options);
          hightLight(params);
        });
      isClickPoint &&
        onClickPoint &&
        myChart.on("click", "series.line", (params: any) => {
          onClickPoint(params.data[0]);
        });
      isHoverPoint &&
        myChart.on("mouseout", "series.line", (params: any) => {
          options.tooltip.show = true;
          myChart.setOption(options);
          removeHightLight(params);
        });
      if (isHoverPoint) {
        renderLable();
        refreshLablePosition(myChart);
      }
    }
  };

  // 窗口大小改变
  const handleChangeSize = () => {
    setTimeout(() => {
      const dom = document.getElementById(idName);
      dom?.removeAttribute("_echarts_instance_");
      handleGenBar();
    }, 1);
  };

  useIoObserve(null, handleChangeSize, idName);
  useEffect(() => {
    handleGenBar();
    window.addEventListener("resize", handleChangeSize);
    return () => {
      const dom = document.getElementById(idName);
      dom?.removeAttribute("_echarts_instance_");
      window.removeEventListener("resize", handleChangeSize);
    };
  }, [JSON.stringify(data), events, xAxis]);

  const renderLable = () => {
    // console.log(events)

    if (!events) return;
    let itemHtmls: any = [];
    data.forEach((v) => {
      // console.log(v.label, pointLegend);

      if (v.label === pointLegend) {
        v.value.forEach((m) => {
          if (m.content) {
            // console.log(m);

            itemHtmls.push(renderItem(m));
          }
        });
      }
    });

    // console.log(itemHtmls)

    const $html = document.createElement("div");
    $html.className = "echarts_ponit_area";
    $html.innerHTML = itemHtmls.join("");
    const dom = document.getElementById(idName);
    dom.appendChild($html);
  };

  const renderItem = (item: any, bool?: boolean) => {
    return `
     <div class="echarts_mark_point_box${
       bool ? "label_height_light" : ""
     }" data-key='${item.key}' data-value='${item.value}' data-content'${
      item.content
    }>
      <div class='echarts_mark_point_content'>${item.key} :<br />${
      item.content
    }</div>
     </div>
   `;
  };

  return (
    <div
      id={idName}
      className={styles.echarts_box}
      style={{ width: "100%", height: "100%" }}
    ></div>
  );
};

export default EventLine;
